import os
import struct
import datetime
import math
import numpy
import sys
import pandas

# 通达信日线数据格式
# 00 ~ 01 字节: 日期，整型；计算方法为：year = floor(num/2048) + 2004;  month = floor(mod(num,2048)/100);   day = mod(mod(num,2048), 100);
# 02 ~ 03 字节: 0点至目前的分钟数，整型
# 04 ~ 07 字节: 开盘价*100，整型
# 08 ~ 11 字节: 最高价*100，整型
# 12 ~ 15 字节: 最低价*100，整型
# 16 ~ 19 字节: 收盘价*100，整型
# 20 ~ 23 字节: 成交额*100，float型
# 24 ~ 27 字节: 成交量（股），整型
# 28 ~ 31 字节: （保留）
def stockFile(source):
    datalist = []
    dates = []
    name = source.split("#")[1].split(".")[0]
    with open(source, 'rb') as f:
        while True:
            stock_date = f.read(2)
            stock_minute = f.read(2)
            stock_open = f.read(4)
            stock_high = f.read(4)
            stock_low = f.read(4)
            stock_close = f.read(4)
            stock_amount = f.read(4)
            stock_vol = f.read(4)
            stock_reservation = f.read(4)  # date,open,high,low,close,amount,vol,reservation
            if not stock_date:
                break
            # 取整: math.floor(a/b) 或 a//b
            # 取余: numpy.mod(a, b) 或 a%b
            year = math.floor(struct.unpack("H", stock_date)[0] / 2048) + 2004
            month = math.floor(numpy.mod(struct.unpack("H", stock_date)[0], 2048) / 100)
            day = numpy.mod(numpy.mod(struct.unpack("H", stock_date)[0], 2048), 100)
            # 北京时间0点至当前时间的分钟数
            minute = struct.unpack("H", stock_minute)[0]
            # 开盘价
            stock_open = round(struct.unpack("f", stock_open)[0], 2)
            # 最高价
            stock_high = round(struct.unpack("f", stock_high)[0], 2)
            # 最低价
            stock_low = round(struct.unpack("f", stock_low)[0], 2)
            # 收盘价
            stock_close = round(struct.unpack("f", stock_close)[0], 2)
            # 成交量
            stock_vol = struct.unpack("l", stock_vol)[0]
            # 成交额
            stock_amount = round(struct.unpack("f", stock_amount)[0])
            # 保留值
            stock_reservation = struct.unpack("l", stock_reservation)[0]
            # 格式化日期
            dates.append(str(year) + "-" + str(month) + "-" + str(day) + " " + str(minute//60) + ":" + str(numpy.mod(minute, 60)))
            data = "[" + str(minute) + ", " + str(stock_open) + ", " + str(stock_high) + ", " + str(stock_low) + ", " + str(stock_close) + ", " + str(stock_vol) + ", " + str(stock_amount) + "]"
            datalist.append(data)
        return name, dates, datalist

# ['BIIB', 'OGN', 'VTRS'] z这三个数据不全
def stock(rootPath, dataFile):
    # w+ 表示打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。
    dic = {}
    listfile = os.listdir(rootPath)
    for i in range(len(listfile)):
        name, dates, datalist = stockFile(rootPath + listfile[i])
        if i == 0:
            dic['时间'] = dates
        if len(datalist) != len(dic['时间']):
            print("代码 " + name + " 数据不全, 已经丢弃")
            continue
        dic[name] = datalist
    dataFrame = pandas.DataFrame(dic)
    dataFrame.to_csv(dataFile, index=False, sep=';')

# 文件夹下个股数据必须是统一开始日期到结束日期的数据
# 通道格式: [北京时间当天分钟数, 开盘价, 最高价, 最低价, 收盘价, 成交量, 成交额]
if __name__ == '__main__':
    stock('../temp/data/通信达/分钟线/', "../temp/data/通信达/分钟线.csv")
    sys.exit(1)